﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace CoolCode
{
    public static class VProvider
    {
        public static Validation CreateValidator()
        {
            return new Validation();
        }

        public static Validation CreateValidator(this string value)
        {
            return new Validation(value);
        }

        public static Validation CreateValidator(this string value, string label)
        {
            return new Validation(value, label);
        }
    }

    public enum ValidationType
    {
        /// <summary>
        /// 验证所有错误
        /// </summary>
        All,
        /// <summary>
        /// 一旦验证到一个错误即终止
        /// </summary>
        Once
    }

    public class Validation : IEnumerable<IValidatingMessage>
    {
        private List<IValidatingMessage> _errors = new List<IValidatingMessage>();

        public bool IsValid { get; set; }
        public string Value { get; set; }
        public string Property { get; set; }

        public Validation()
            : this(string.Empty)
        { 
        }

        public Validation(string value)
            : this(value, string.Empty)
        {
        }

        public Validation(string value, string property) 
        {
            Value = value;
            Property = property;
            IsValid = true; 
        }

        public Validation SetValue(string value)
        {
            Value = value;
            return this;
        }

        public Validation NotEmpty()
        {
            if (IsValid)
            {
                IsValid = !string.IsNullOrEmpty(Value);
                if (IsValid)
                    IsValid = (Value.Trim() != string.Empty);
                if (!IsValid)
                    _errors.Add( new ValidatingMessage( Property ,  "E0033") ) ;
            }
            return this;
        }

        public Validation Range(string textFrom, string textTo)
        {
            if (IsValid)
            {
                IsValid = !(string.Compare(textFrom, textTo) == 1);
                if (!IsValid)
                    _errors.Add(new ValidatingMessage(Property, "E0007", textFrom ,textTo ));
            }
            return this;
        }

        public Validation Range(DateTime dateFrom, DateTime dateTo)
        {
            if (IsValid)
            {
                IsValid = !(DateTime.Compare(dateFrom, dateTo) == 1);
                if (!IsValid)
                    _errors.Add(new ValidatingMessage(Property, "E0007",dateFrom,dateTo ));
            }
            return this;
        }

        public Validation ShorterThan(int length)
        {
            if (IsValid)
            {
                if (length <= 0) return this;
                IsValid = (Value.Length <= length);
                if (!IsValid)
                    _errors.Add(new ValidatingMessage(Property, "E0034",length ));
            }
            return this;
        }

        public Validation LongerThan(int length)
        {
            if (IsValid)
            {
                if (length <= 0) return this;
                IsValid = (Value.Length >= length);
                if (!IsValid)
                    _errors.Add(new ValidatingMessage(Property, "E0035", length));
            }
            return this;
        }

        public Validation Between(int minLength, int maxLength)
        {
            if (IsValid)
            { 
                IsValid = (Value.Length >= minLength && Value.Length <=maxLength ) ;
                if (!IsValid)
                    _errors.Add(new ValidatingMessage(Property, "E0036", minLength, maxLength ));
            }
            return this;
        }

        public Validation IsEmail()
        {
            if (IsValid)
            {
                 IsValid = Value.IsEmail();
                 if (!IsValid)
                     _errors.Add(new ValidatingMessage(Property, "E0037"));                     
            }
            return this; 
        }

        #region IEnumerable<IValidatingMessage> Members

        public IEnumerator<IValidatingMessage> GetEnumerator()
        {
            return _errors.GetEnumerator ();
        }

        #endregion

        #region IEnumerable Members

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }

        #endregion
    }

}
